package com.example.webview_pdf_demo;

import android.Manifest;
import android.content.Context;
import android.graphics.Bitmap;
import android.os.Build;
import android.os.Bundle;
import android.os.CancellationSignal;
import android.os.Environment;
import android.os.ParcelFileDescriptor;
import android.os.PersistableBundle;
import android.print.PageRange;
import android.print.PrintAttributes;
import android.print.PrintDocumentAdapter;
import android.util.Log;
import android.view.View;
import android.webkit.WebChromeClient;
import android.webkit.WebResourceError;
import android.webkit.WebResourceRequest;
import android.webkit.WebResourceResponse;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.ProgressBar;

import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.PermissionChecker;

import java.io.File;
import java.io.IOException;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;

public class MainActivity extends AppCompatActivity {

    private ProgressBar progressBar;
    private WebView webview;
    private WebSettings webSettings;
    private String pdfPath;
    @Override
    public void onCreate(@Nullable Bundle savedInstanceState, @Nullable PersistableBundle persistentState) {
        super.onCreate(savedInstanceState, persistentState);
        progressBar = findViewById(R.id.progressBar);
        webview = findViewById(R.id.webView);
        webSettings = webview.getSettings();
        pdfPath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/test.pdf";

        setContentView(R.layout.activity_main_a);
        progressBar.setVisibility(View.VISIBLE);
        webview.setVisibility(View.VISIBLE);
        webview.setWebChromeClient(new WebChromeClient());

        setupWebSettings();
        setupWebViewClient();

        webview.loadUrl("https://www.baidu.com");
    }

    private void setupWebSettings(){
        webSettings.setAllowContentAccess(true);
        webSettings.setAllowFileAccess(true);
        webSettings.setBuiltInZoomControls(false);
        webSettings.setDisplayZoomControls(true);
        webSettings.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.NORMAL);
        webSettings.setJavaScriptEnabled(true);

        webSettings.setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);
        webSettings.setAppCacheEnabled(true);
        webSettings.setDomStorageEnabled(true); //default is false

        webSettings.setBlockNetworkImage(false);
        webSettings.setBlockNetworkLoads(false);
        webSettings.setDatabaseEnabled(true);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            webSettings.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
        }
    }

    private void setupWebViewClient(){
        webview.setWebViewClient(new WebViewClient(){
            @Override
            public void onPageStarted(WebView view, String url, Bitmap favicon) {
                super.onPageStarted(view, url, favicon);
            }

            @Override
            public void onPageCommitVisible(WebView view, String url) {
                super.onPageCommitVisible(view, url);
            }

            @Override
            public void onPageFinished(WebView view, String url) {
                super.onPageFinished(view, url);
                progressBar.setVisibility(View.INVISIBLE);
            }

            @Override
            public void onReceivedHttpError(WebView view, WebResourceRequest request, WebResourceResponse errorResponse) {
                super.onReceivedHttpError(view, request, errorResponse);
                progressBar.setVisibility(View.INVISIBLE);
            }

            @Override
            public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) {
                super.onReceivedError(view, request, error);
                progressBar.setVisibility(View.INVISIBLE);
            }
        });
    }

    private void drawPdf(){
        Boolean hasPermission = ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PermissionChecker.PERMISSION_GRANTED;
        if (!hasPermission){
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 202);
            return;
        }
        webviewToPdf();
    }

    private void webviewToPdf(){
       try{
           File pdfFile = new File(pdfPath);
           if (pdfFile.exists()){
               pdfFile.delete();
           }
           pdfFile.createNewFile();
           ParcelFileDescriptor descriptor = ParcelFileDescriptor.open(pdfFile,ParcelFileDescriptor.MODE_READ_WRITE);
           PrintAttributes attributes = new PrintAttributes.Builder()
                   .setColorMode(PrintAttributes.COLOR_MODE_COLOR)
                   .setResolution(new PrintAttributes.Resolution("id", Context.PRINT_SERVICE, 500,500))
                   .setMinMargins(PrintAttributes.Margins.NO_MARGINS)
                   .setMediaSize(PrintAttributes.MediaSize.ISO_A4)
                   .build();
           int numberOfPages = (int)(webview.getContentHeight() * 500/(PrintAttributes.MediaSize.ISO_A4.getHeightMils()));
           PageRange[] ranges = new PageRange[]{new PageRange(0,numberOfPages)};
           PrintDocumentAdapter printDocumentAdapter = webview.createPrintDocumentAdapter("webviewPdf");
           printDocumentAdapter.onStart();
           printDocumentAdapter.onLayout(attributes,attributes, new CancellationSignal(), (new PrintDocumentAdapter.LayoutResultCallback(){

           }) );
       } catch (Exception execption) {
           Log.e("PdfConvert", execption.toString());
        }
    }


    private static PrintDocumentAdapter.LayoutResultCallback getLayoutResultCallback (InvocationHandler invocationHandler) throws IOException {

        InvocationHandler handler =  Proxy.getInvocationHandler()

        return Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(), PrintDocumentAdapter.LayoutResultCallback.class.getInterfaces(), invocationHandler);
    }
}